﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Sofire.DataComm.Remoting.Server.Settings;
using System.IO;
using System.Xml;

namespace Sofire.DataComm.Remoting.Server.Settings
{
    /// <summary>
    /// 表示读取配置时的异常信息。
    /// </summary>
    public class SettingException : Exception
    {
        internal ApplicationSetting _Application;
        /// <summary>
        /// 获取配置文件的应用程序配置信息。
        /// </summary>
        public ApplicationSetting Application
        {
            get
            {
                return this._Application;
            }
        }

        internal HostSetting _Host;
        /// <summary>
        /// 获取配置文件的主机配置信息。
        /// </summary>
        public HostSetting Host
        {
            get
            {
                return this._Host;
            }
        }

        internal ServiceSetting _Service;
        /// <summary>
        /// 获取配置文件的服务配置信息。
        /// </summary>
        public ServiceSetting Service
        {
            get
            {
                return this._Service;
            }
        }

        private ServerErrorCode _ErrorCode;
        /// <summary>
        /// 获取配置文件的异常代码。
        /// </summary>
        public ServerErrorCode ErrorCode
        {
            get
            {
                return this._ErrorCode;
            }
        }

        private string _PropertyName;
        /// <summary>
        /// 获取引发异常的属性名。
        /// </summary>
        public string PropertyName
        {
            get
            {
                return this._PropertyName;
            }
        }

        private string _PropertyValue;
        /// <summary>
        /// 获取引发异常的属性值。
        /// </summary>
        public string PropertyValue
        {
            get
            {
                return this._PropertyValue;
            }
        }

        const string FullMessageFormat =
@"[ErrorCode]: {0}
[Application]: {1}
[Host]: {2}
[ServiceSetting]: {3}
[PropertyName]: {4}
[PropertyValue]: {5}";
        /// <summary>
        /// 获取完整的错误信息。
        /// </summary>
        public string FullMessage
        {
            get
            {
                return string.Format(FullMessageFormat
                    , this._ErrorCode
                    , this._Application == null ? "NULL" : this._Application.Name
                    , this._Host == null ? "NULL" : this._Host.Name
                    , this._Service == null ? "NULL" : this._Service.Name
                    , this._PropertyName ?? "NONE"
                    , this._PropertyValue ?? "NONE");
            }
        }

        internal SettingException() { }

        internal SettingException(ServerErrorCode errorCode) : this(errorCode, null, null) { }

        internal SettingException(ServerErrorCode errorCode, string propertyName) : this(errorCode, propertyName, null) { }

        internal SettingException(ServerErrorCode errorCode, string propertyName, string propertyValue)
            : base(ErrorCodeInfos[errorCode])
        {
            this._ErrorCode = errorCode;
            this._PropertyName = propertyName;
            this._PropertyValue = propertyValue;
        }

        private readonly static Dictionary<ServerErrorCode, string> ErrorCodeInfos;

        static string GetCultureOwnerName(System.Globalization.CultureInfo culture)
        {
            if(string.IsNullOrEmpty(culture.Parent.Name)) return culture.Name;
            return GetCultureOwnerName(culture.Parent);
        }

        static SettingException()
        {

            XmlDocument document = new XmlDocument();

            var culture = System.Threading.Thread.CurrentThread.CurrentCulture;
            var name = GetCultureOwnerName(culture);

            bool found = false;
            if(name != "zh-Hans")
            {
                string path = "SettingException." + name + ".xml";
                if(File.Exists(path))
                {
                    document.Load(path);
                    found = true;
                }
            }

            if(!found)
            {
                var stream = typeof(SettingException).Assembly.GetManifestResourceStream("Sofire.DataComm.Remoting.Server.Settings.SettingException.xml");

                document.Load(stream);
            }

            var errorElements = document.DocumentElement.SelectNodes("Error");
            ErrorCodeInfos = new Dictionary<ServerErrorCode, string>(errorElements.Count);
            foreach(XmlElement element in errorElements)
            {
                var code = element.GetAttribute("Code");
                var message = element.InnerText;
                ErrorCodeInfos.Add((ServerErrorCode)Enum.Parse(typeof(ServerErrorCode), code), message);
            }
        }

        /// <summary>
        /// 返回当前异常的字符串表示形式。
        /// </summary>
        /// <returns>异常的字符串表示形式。</returns>
        public override string ToString()
        {
            var message = base.ToString();

            return FullMessage + "\r\n" + message;
        }
    }

}
